#pragma once
#ifdef __cplusplus
#ifndef _HAS_EXCEPTIONS
#define _HAS_EXCEPTIONS 0
#endif
#endif

#include <initguid.h>
#include <fltKernel.h>
#include <windef.h>
#include <ntimage.h>

#pragma warning( disable : 4047 4055 4127 4200 4201 4204 4324)
typedef unsigned __int64		QWORD, *PQWORD;
/*

typedef char                CHAR;
typedef signed char         INT8;
typedef unsigned char       UCHAR;
typedef unsigned char       UINT8;
typedef unsigned char       BYTE;
typedef short               SHORT;
typedef signed short        INT16;
typedef unsigned short      USHORT;
typedef unsigned short      UINT16;
typedef unsigned short      WORD;
typedef int                 INT;
typedef signed int          INT32;
typedef unsigned int        UINT;
typedef unsigned int        UINT32;
typedef long                LONG;
typedef unsigned long       ULONG;
typedef unsigned long       DWORD;
typedef __int64             LONGLONG;
typedef __int64             LONG64;
typedef signed __int64      INT64;
typedef unsigned __int64    ULONGLONG;
typedef unsigned __int64    DWORDLONG;
typedef unsigned __int64    ULONG64;
typedef unsigned __int64    DWORD64;
typedef unsigned __int64    UINT64;
typedef wchar_t WCHAR;
typedef __int64             INT_PTR;
typedef unsigned __int64    UINT_PTR;
typedef __int64             LONG_PTR;
typedef unsigned __int64    ULONG_PTR;

#define _In_
#define _Out_
#define _In_opt_
#define _Inout_
#define _In_reads_bytes_opt_(s)
#define _In_reads_bytes_(s)
#define _Out_opt_
#define UNALIGNED __unaligned
#define CONST const
#define _Null_terminated_
#define _NullNull_terminated_
#define _In_z_
#define EXTERN_C    extern "C"
#define DUMMYUNIONNAME
#define DUMMYUNIONNAME2
#define DUMMYUNIONNAME3
#define DUMMYUNIONNAME4
#define DUMMYUNIONNAME5
#define DUMMYUNIONNAME6
#define DUMMYUNIONNAME7
#define DUMMYUNIONNAME8
#define DUMMYUNIONNAME9


typedef WCHAR *PWCHAR, *LPWCH, *PWCH;
typedef const WCHAR *LPCWCH, *PCWCH;

typedef _Null_terminated_ WCHAR *NWPSTR, *LPWSTR, *PWSTR;
typedef _Null_terminated_ PWSTR *PZPWSTR;
typedef _Null_terminated_ CONST PWSTR *PCZPWSTR;
typedef _Null_terminated_ WCHAR UNALIGNED *LPUWSTR, *PUWSTR;
typedef _Null_terminated_ CONST WCHAR *LPCWSTR, *PCWSTR;
typedef _Null_terminated_ PCWSTR *PZPCWSTR;
typedef _Null_terminated_ CONST PCWSTR *PCZPCWSTR;
typedef _Null_terminated_ CONST WCHAR UNALIGNED *LPCUWSTR, *PCUWSTR;

typedef _NullNull_terminated_ WCHAR *PZZWSTR;
typedef _NullNull_terminated_ CONST WCHAR *PCZZWSTR;
typedef _NullNull_terminated_ WCHAR UNALIGNED *PUZZWSTR;
typedef _NullNull_terminated_ CONST WCHAR UNALIGNED *PCUZZWSTR;

typedef  WCHAR *PNZWCH;
typedef  CONST WCHAR *PCNZWCH;
typedef  WCHAR UNALIGNED *PUNZWCH;
typedef  CONST WCHAR UNALIGNED *PCUNZWCH;


typedef CHAR *PCHAR, *LPCH, *PCH;
typedef CONST CHAR *LPCCH, *PCCH;

typedef _Null_terminated_ CHAR *NPSTR, *LPSTR, *PSTR;
typedef _Null_terminated_ PSTR *PZPSTR;
typedef _Null_terminated_ CONST PSTR *PCZPSTR;
typedef _Null_terminated_ CONST CHAR *LPCSTR, *PCSTR;
typedef _Null_terminated_ PCSTR *PZPCSTR;
typedef _Null_terminated_ CONST PCSTR *PCZPCSTR;

typedef _NullNull_terminated_ CHAR *PZZSTR;
typedef _NullNull_terminated_ CONST CHAR *PCZZSTR;

typedef  CHAR *PNZCH;
typedef  CONST CHAR *PCNZCH;

typedef void *PVOID;
typedef void *PVOID64;
typedef PVOID HANDLE;

typedef char CCHAR;          // winnt
typedef short CSHORT;
typedef ULONG CLONG;

typedef CCHAR *PCCHAR;
typedef CSHORT *PCSHORT;
typedef CLONG *PCLONG;

typedef ULONG_PTR SIZE_T, *PSIZE_T;
typedef LONG_PTR SSIZE_T, *PSSIZE_T;
#define VOID void
typedef UCHAR BOOLEAN;           // winnt
typedef BOOLEAN *PBOOLEAN;       // winnt

typedef signed char         INT8, *PINT8;
typedef signed short        INT16, *PINT16;
typedef signed int          INT32, *PINT32;
typedef signed __int64      INT64, *PINT64;
typedef unsigned char       UINT8, *PUINT8;
typedef unsigned short      UINT16, *PUINT16;
typedef unsigned int        UINT32, *PUINT32;
typedef unsigned __int64    UINT64, *PUINT64;

typedef struct _QUAD {
	union {
		__int64 UseThisFieldToCopy;
		double  DoNotUseThisField;
	} DUMMYUNIONNAME;

} QUAD;

typedef HANDLE *PHANDLE;
typedef ULONG ACCESS_MASK;
typedef ACCESS_MASK *PACCESS_MASK;
typedef ULONG *PULONG;
typedef BYTE           *PBYTE;
typedef BYTE           *LPBYTE;
typedef SHORT *PSHORT;  // winnt
typedef LONG *PLONG;    // winnt
typedef QUAD *PQUAD;

#define MAX_PATH          260
#define TRUE                1
#define FALSE               0
#define NULL    0
typedef DWORD *PDWORD;
typedef USHORT *PUSHORT;
typedef WORD *PWORD;
#define NTAPI __stdcall
//////////////////////////////////////////////////////////////////////////
typedef LONG NTSTATUS;
typedef NTSTATUS *PNTSTATUS;
typedef UCHAR KIRQL;
typedef KIRQL *PKIRQL;
typedef struct _EPROCESS *PEPROCESS;
typedef struct _ETHREAD *PETHREAD;
typedef struct _GUID {
	unsigned long  Data1;
	unsigned short Data2;
	unsigned short Data3;
	unsigned char  Data4[8];
} GUID;
typedef GUID CLSID;
//#define _bs64 _byteswap_uint64  
#define _bs32(x) ((x << 24) | (x >> 24) | ((x << 8) & 0x00ff0000 ) | ((x >> 8) & 0x0000ff00))
#define _bs16(x) ((x << 8) | (x >> 8))

#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define NT_INFORMATION(Status) ((((ULONG)(Status)) >> 30) == 1)
#define NT_WARNING(Status) ((((ULONG)(Status)) >> 30) == 2)
#define NT_ERROR(Status) ((((ULONG)(Status)) >> 30) == 3)

#define OBJ_CASE_INSENSITIVE    				0x00000040
#define FILE_SYNCHRONOUS_IO_NONALERT			0x00000020
#define FILE_OPEN								0x00000001
#define FILE_OPEN_IF							0x00000003
#define FILE_OVERWRITE_IF						0x00000005
#define OBJ_KERNEL_HANDLE       				0x00000200
#define FILE_NON_DIRECTORY_FILE                 0x00000040

#define GENERIC_READ                     (0x80000000L)
#define GENERIC_WRITE                    (0x40000000L)
#define GENERIC_EXECUTE                  (0x20000000L)
#define GENERIC_ALL                      (0x10000000L)

#define DELETE                           (0x00010000L)
#define READ_CONTROL                     (0x00020000L)
#define WRITE_DAC                        (0x00040000L)
#define WRITE_OWNER                      (0x00080000L)
#define SYNCHRONIZE                      (0x00100000L)

#define STANDARD_RIGHTS_REQUIRED         (0x000F0000L)

#define STANDARD_RIGHTS_READ             (READ_CONTROL)
#define STANDARD_RIGHTS_WRITE            (READ_CONTROL)
#define STANDARD_RIGHTS_EXECUTE          (READ_CONTROL)

#define STANDARD_RIGHTS_ALL              (0x001F0000L)

#define SPECIFIC_RIGHTS_ALL              (0x0000FFFFL)

#define FILE_ATTRIBUTE_READONLY             0x00000001  
#define FILE_ATTRIBUTE_HIDDEN               0x00000002  
#define FILE_ATTRIBUTE_SYSTEM               0x00000004  
//OLD DOS VOLID                             0x00000008

#define FILE_ATTRIBUTE_DIRECTORY            0x00000010  
#define FILE_ATTRIBUTE_ARCHIVE              0x00000020  
#define FILE_ATTRIBUTE_DEVICE               0x00000040  
#define FILE_ATTRIBUTE_NORMAL               0x00000080  

#define FILE_ATTRIBUTE_TEMPORARY            0x00000100  
#define FILE_ATTRIBUTE_SPARSE_FILE          0x00000200  
#define FILE_ATTRIBUTE_REPARSE_POINT        0x00000400  
#define FILE_ATTRIBUTE_COMPRESSED           0x00000800  

#define FILE_ATTRIBUTE_OFFLINE              0x00001000  
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000  
#define FILE_ATTRIBUTE_ENCRYPTED            0x00004000  


#define UNREFERENCED_PARAMETER(P)          (P)
#define DBG_UNREFERENCED_PARAMETER(P)      (P)
#define DBG_UNREFERENCED_LOCAL_VARIABLE(V) (V)

typedef enum _POOL_TYPE {
	NonPagedPool,
	NonPagedPoolExecute = NonPagedPool,
	PagedPool,
	NonPagedPoolMustSucceed = NonPagedPool + 2,
	DontUseThisType,
	NonPagedPoolCacheAligned = NonPagedPool + 4,
	PagedPoolCacheAligned,
	NonPagedPoolCacheAlignedMustS = NonPagedPool + 6,
	MaxPoolType,

	//
	// Define base types for NonPaged (versus Paged) pool, for use in cracking
	// the underlying pool type.
	//

	NonPagedPoolBase = 0,
	NonPagedPoolBaseMustSucceed = NonPagedPoolBase + 2,
	NonPagedPoolBaseCacheAligned = NonPagedPoolBase + 4,
	NonPagedPoolBaseCacheAlignedMustS = NonPagedPoolBase + 6,

	//
	// Note these per session types are carefully chosen so that the appropriate
	// masking still applies as well as MaxPoolType above.
	//

	NonPagedPoolSession = 32,
	PagedPoolSession = NonPagedPoolSession + 1,
	NonPagedPoolMustSucceedSession = PagedPoolSession + 1,
	DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1,
	NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1,
	PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1,
	NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1,

	NonPagedPoolNx = 512,
	NonPagedPoolNxCacheAligned = NonPagedPoolNx + 4,
	NonPagedPoolSessionNx = NonPagedPoolNx + 32,

} POOL_TYPE;

typedef struct _UNICODE_STRING {
	USHORT Length;
	USHORT MaximumLength;
	PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _ANSI_STRING {
	USHORT Length;
	USHORT MaximumLength;
	PCHAR  Buffer;
} ANSI_STRING, *PANSI_STRING;

typedef struct _OBJECT_ATTRIBUTES {
	ULONG Length;
	HANDLE RootDirectory;
	PUNICODE_STRING ObjectName;
	ULONG Attributes;
	PVOID SecurityDescriptor;
	PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;

typedef struct _IO_STATUS_BLOCK {
	union {
		NTSTATUS Status;
		PVOID Pointer;
	} DUMMYUNIONNAME;

	ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;


#define InitializeObjectAttributes( p, n, a, r, s ) { \
    (p)->Length = sizeof( OBJECT_ATTRIBUTES );          \
    (p)->RootDirectory = r;                             \
    (p)->Attributes = a;                                \
    (p)->ObjectName = n;                                \
    (p)->SecurityDescriptor = s;                        \
    (p)->SecurityQualityOfService = NULL;               \
    }
	*/
typedef enum _SYSTEM_INFORMATION_CLASS {
	SystemProcessInformation = 5,
	SystemModuleInformation = 11,
} SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS;

typedef struct _RTL_PROCESS_MODULE_INFORMATION {
	HANDLE Section;                 // Not filled in
	PVOID MappedBase;
	PVOID ImageBase;
	ULONG ImageSize;
	ULONG Flags;
	USHORT LoadOrderIndex;
	USHORT InitOrderIndex;
	USHORT LoadCount;
	USHORT OffsetToFileName;
	UCHAR  FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;

typedef struct _RTL_PROCESS_MODULES {
	ULONG NumberOfModules;
	RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;

/*
typedef CCHAR KPROCESSOR_MODE;

typedef enum _MODE {
	KernelMode,
	UserMode,
	MaximumMode
} MODE;

typedef enum _MEMORY_CACHING_TYPE {
	MmNonCached = 0,
	MmCached = 1,
	MmWriteCombined = 2,
	MmHardwareCoherentCached = 3,
	MmNonCachedUnordered = 4,
	MmUSWCCached = 5,
	MmMaximumCacheType = 6
} MEMORY_CACHING_TYPE;

typedef union _LARGE_INTEGER {
	struct {
		ULONG LowPart;
		LONG HighPart;
	} DUMMYSTRUCTNAME;
	struct {
		ULONG LowPart;
		LONG HighPart;
	} u;
	LONGLONG QuadPart;
} LARGE_INTEGER;
typedef LARGE_INTEGER *PLARGE_INTEGER;

size_t  __cdecl strlen(_In_z_ const char * _Str);
*/
#undef RtlCopyMemory
#undef RtlZeroMemory
#undef ExFreePool
typedef struct tdKERNEL_FUNCTIONS {
	int(*_stricmp)(
		const char *string1,
		const char *string2);
	PVOID(*ExAllocatePool)(
		_In_ QWORD PoolType,
		_In_ SIZE_T NumberOfBytes);
	VOID(*ExFreePool)(
		_In_ PVOID P);
	NTSTATUS(*IoCreateDriver)(
		_In_opt_ PUNICODE_STRING DriverName,
		_In_ QWORD  PDriverEntry
		);
	NTSTATUS(*KeDelayExecutionThread)(
		_In_ KPROCESSOR_MODE WaitMode,
		_In_ BOOLEAN         Alertable,
		_In_ PLARGE_INTEGER  pllInterval_Neg100ns
		);
	KIRQL(*KeGetCurrentIrql)(
		);
	QWORD(*MmGetPhysicalAddress)(
		_In_ PVOID BaseAddress
		);
	NTSTATUS(*MmLoadSystemImage)(
		_In_ PUNICODE_STRING  FileName,
		_In_opt_ PUNICODE_STRING NamePrefix,
		_In_opt_ PUNICODE_STRING LoadedName,
		_In_ ULONG  Flags,
		_Out_ PVOID *ModuleObject,
		_Out_ PVOID *ImageBaseAddress
		);
	PVOID(*MmMapIoSpace)(
		_In_  QWORD  PhysicalAddress,
		_In_  SIZE_T NumberOfBytes,
		_In_  MEMORY_CACHING_TYPE CacheType
		);
	NTSTATUS(*MmUnloadSystemImage)(
		_In_ PVOID *ModuleObject
		);
	VOID(*MmUnmapIoSpace)(
		_In_  PVOID  BaseAddress,
		_In_  SIZE_T NumberOfBytes
		);
	NTSTATUS(*RtlAnsiStringToUnicodeString)(
		_Inout_ PUNICODE_STRING DestinationString,
		_In_    PANSI_STRING    SourceString,
		_In_    BOOLEAN         AllocateDestinationString
		);
	VOID(*RtlCopyMemory)(
		_Out_ VOID UNALIGNED *Destination,
		_In_ const VOID UNALIGNED *Source,
		_In_ SIZE_T Length
		);
	VOID(*RtlFreeUnicodeString)(
		_Inout_ PUNICODE_STRING UnicodeString
		);
	VOID(*RtlInitAnsiString)(
		_Out_    PANSI_STRING DestinationString,
		_In_opt_ PCSTR         SourceString
		);
	VOID(*RtlInitUnicodeString)(
		_Out_ PUNICODE_STRING DestinationString,
		_In_opt_ PCWSTR SourceString
		);
	VOID(*RtlZeroMemory)(
		_Out_ VOID UNALIGNED *Destination,
		_In_ SIZE_T Length
		);
	NTSTATUS(*ZwClose)(
		_In_ HANDLE hObject
		);
	NTSTATUS(*ZwCreateFile)(
		_Out_	 PHANDLE			FileHandle,
		_In_	 ACCESS_MASK		DesiredAccess,
		_In_	 PVOID				ObjectAttributes,
		_Out_	 PIO_STATUS_BLOCK	IoStatusBlock,
		_In_opt_ PLARGE_INTEGER		AllocationSize,
		_In_	 ULONG				FileAttributes,
		_In_	 ULONG				ShareAccess,
		_In_	 ULONG				CreateDisposition,
		_In_	 ULONG				CreateOptions,
		_In_reads_bytes_opt_(EaLength) PVOID EaBuffer,
		_In_	 ULONG				EaLength
		);
	NTSTATUS(*ZwOpenFile)(
		_Out_	 PHANDLE            FileHandle,
		_In_	 ACCESS_MASK        DesiredAccess,
		_In_	 POBJECT_ATTRIBUTES ObjectAttributes,
		_Out_	 PIO_STATUS_BLOCK   IoStatusBlock,
		_In_	 ULONG              ShareAccess,
		_In_	 ULONG              OpenOptions
		);
	NTSTATUS(*ZwQueryDirectoryFile)(
		_In_	 HANDLE				FileHandle,
		_In_opt_ HANDLE				Event,
		_In_opt_ PVOID				ApcRoutine,
		_In_opt_ PVOID				ApcContext,
		_Out_	 PIO_STATUS_BLOCK	IoStatusBlock,
		_Out_	 PVOID				FileInformation,
		_In_	 ULONG				Length,
		_In_	 QWORD				FileInformationClass,
		_In_	 BOOLEAN			ReturnSingleEntry,
		_In_opt_ PUNICODE_STRING	FileName,
		_In_	 BOOLEAN			RestartScan
		);
	NTSTATUS(*ZwQuerySystemInformation)(
		_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
		_Inout_ PVOID SystemInformation,
		_In_ ULONG SystemInformationLength,
		_Out_opt_ PULONG ReturnLength);
	NTSTATUS(*ZwReadFile)(
		_In_     HANDLE           FileHandle,
		_In_opt_ HANDLE           Event,
		_In_opt_ PVOID			  ApcRoutine,
		_In_opt_ PVOID            ApcContext,
		_Out_    PIO_STATUS_BLOCK IoStatusBlock,
		_Out_    PVOID            Buffer,
		_In_     ULONG            Length,
		_In_opt_ PQWORD           ByteOffset,
		_In_opt_ PULONG           Key
		);
	NTSTATUS(*ZwSetSystemInformation)(
		_In_ QWORD SystemInformationClass,
		_In_ PVOID SystemInformation,
		_In_ ULONG SystemInformationLength
		);
	NTSTATUS(*ZwWriteFile)(
		_In_ HANDLE FileHandle,
		_In_opt_ HANDLE Event,
		_In_opt_ PVOID ApcRoutine,
		_In_opt_ PVOID ApcContext,
		_Out_ PVOID IoStatusBlock,
		_In_reads_bytes_(Length) PVOID Buffer,
		_In_ ULONG Length,
		_In_opt_ PLARGE_INTEGER ByteOffset,
		_In_opt_ PULONG Key
		);
	decltype(&strlen) _strlen;
	decltype(&DbgPrintEx) _DbgPrintEx;
	decltype(&PsCreateSystemThread) _PsCreateSystemThread;
	PVOID pvStart;
} KERNEL_FUNCTIONS, *PKERNEL_FUNCTIONS;

#define _RELATIVE(x)		-(x)
#define _SECONDS(x)			(LONGLONG)x*10000000
#define _MILLISECONDS(x)	(LONGLONG)x*10000
#define _MINUTES(x)			(LONGLONG)x*600000000

// ----------------------------- ROR13 HASHES BELOW -----------------------------

#include "ntos_hash.h"
#include "ci_hash.h"

// ----------------------------- FUNCTION DECLARATIONS BELOW -----------------------------

DWORD HashROR13A(_In_ LPCSTR sz);
QWORD PEGetProcAddressH(_In_ QWORD hModule, _In_ DWORD dwProcNameH);
VOID InitializeKernelFunctions(_In_ QWORD qwNtosBase, _Out_ PKERNEL_FUNCTIONS fnk);
DWORD PEGetImageSize(_In_ QWORD hModule);
QWORD KernelGetModuleBase(_In_ PKERNEL_FUNCTIONS fnk, _In_ LPSTR szModuleName);
VOID CommonSleep(_In_ PKERNEL_FUNCTIONS fnk, _In_ DWORD ms);

EXTERN_C QWORD GetCR3();
EXTERN_C VOID CacheFlush();

